package com.example.multidatasource.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.sql.SQLException;

@Slf4j
@Setter
@Getter
@Configuration
@ConfigurationProperties(prefix = "spring.datasource.primary")
public class DruidDataSourceProperties {
    private String dbName;
    private String url;
    private String username;
    private String password;
    private String driverClassName;
    private int initSize = 10;
    private int minIdle = 3;
    private int maxActive = 60;
    private int maxWaitting = 60000;
    private boolean removeAbandoned = true;
    private int removeAbandonedTimeOut = 180;
    private int timeBetweenEviction = 60000;
    private long minEvictalbeIdleTime = 300000;
    private String validQuery = "SELECT 'x'";
    private boolean testWhileIdle = true;
    private boolean testOnBorrow = false;
    private boolean testOnReturn = false;
    private Boolean poolPreparedStatements = true;
    private Integer maxPoolPreparedStatementPerConnectionSize = 50;
    private String filters = "stat";


    public DruidDataSource config(){
        DruidDataSource druidDataSource = new DruidDataSource();
        return config(druidDataSource);
    }

    public DruidDataSource config(DruidDataSource dataSource){
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        //初始连接数
        dataSource.setInitialSize(initSize);
        //最小空闲连接数
        dataSource.setMinIdle(minIdle);
        //最大连接数
        dataSource.setMaxActive(maxActive);
        //最大等待超时时间
        dataSource.setMaxWait(maxWaitting);
        //超过时间限制是否回收
        dataSource.setRemoveAbandoned(removeAbandoned);
        //超过多长时间会回收
        dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeOut);
        //多长时间进行一次检测，关闭空闲连接，单位是毫秒
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEviction);
        //配置一个连接在池中最小生存的时间，单位是毫秒
        dataSource.setMinEvictableIdleTimeMillis(minEvictalbeIdleTime);
        //配置连接是否失效的查询语句
        dataSource.setValidationQuery(validQuery);
        // 申请连接的时候检测
        dataSource.setTestWhileIdle(testWhileIdle);
        // 申请连接时执行validationQuery检测连接是否有效，配置为true会降低性能
        dataSource.setTestOnBorrow(testOnBorrow);
        // 归还连接时执行validationQuery检测连接是否有效，配置为true会降低性能
        dataSource.setTestOnReturn(testOnReturn);
        // 打开PSCache，并且指定每个连接上PSCache的大小
        dataSource.setPoolPreparedStatements(poolPreparedStatements);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        // 属性类型是字符串，通过别名的方式配置扩展插件，常用的插件有：
        // 监控统计用的filter:stat
        // 日志用的filter:log4j
        // 防御SQL注入的filter:wall
        try {
            dataSource.setFilters(filters);
        } catch (SQLException e) {
            log.error("扩展插件失败.{}", e.getMessage());
        }
        return dataSource;
    }
}
